import type { Reactive, Ref } from "vue"
import { v4 as uuidv4 } from 'uuid'
import useViewEditorStore from '@/store/viewEditor'

const viewEditorStore = useViewEditorStore()

function getConfig(page: any, list: any) {
  // 获取视图的配置
  const res = {
    list: [] as any[],
    config: {
      ...page.data.props || {},
      events: {
        ...page.data.events || {}
      },
      watch: {
        ...page.data.watch || {}
      },
      lifeCircle: {
        ...page.data.lifeCircle || {}
      },
      style: {
        ...page.data.style
      }
    }
  }

  list.forEach((row: any) => {
    if (row.drag.classify.value === 'layout') {
      const grid = {
        id: row.id,
        type: row.drag.compName,
        component: row.drag.compName,
        options: processConfigData(row, true),
        columns: [] as any[]
      }
      row.data.props.columns.forEach((col: any) => {
        const colData = JSON.parse(JSON.stringify(col))
        colData.list = colData.list || []
        colData.list = colData.list.map((cell: any) => {
          return {
            id: cell.id,
            type: cell.drag.compName,
            component: cell.drag.compName,
            label: cell.data.props._compLabel,
            model: cell.data.dataModel.model,
            ...processConfigData(cell)
          }
        })
        grid.columns.push(colData)
      })
      res.list.push(grid)
    } else {
      res.list.push({
        id: row.id,
        type: row.drag.compName,
        component: row.drag.compName,
        label: row.data.props._compLabel,
        model: row.data.dataModel.model,
        ...processConfigData(row)
      })
    }
  })

  return res
}

function processConfigData(config: any, containerEle: boolean = false) {
  const raw = JSON.parse(JSON.stringify(config.data))
  Object.keys(raw).forEach(key => {
    if (key === 'props') {
      if (containerEle && raw[key]['columns']) {
        delete raw[key]['columns']
      }
    }
  })
  return raw
}

function restoreConfig(viewData: any, page: Reactive<any>, list: Ref<any[]>, compUUID: Ref<number>) {
  if (viewData) {
    const view = JSON.parse(JSON.stringify(viewData))
    Object.keys(page.data).forEach(item => {
      Object.keys(page.data[item]).forEach(key => {
        if (['events', 'lifeCircle', 'style'].includes(key)) {
          page.data[item][key] = view.config[item] && view.config[item][key]
        } else {
          page.data[item][key] = view.config[key]
        }
      })
    })
    list.value = view.list.map((ele: any) => {
      let compDef: Record<string, any> | null = null
      if (ele.columns) {
        compDef = reflectConfig(ele.component)
        if (compDef) {
          Object.keys(compDef.data).forEach(item => {
            Object.keys(compDef!.data[item]).forEach(key => {
              compDef!.data[item][key] = ele.options[item][key]
              if (key === 'columns') {
                compDef!.data[item][key] = ele.columns.map((col: any) => {
                  col.list = col.list.map((colComp: any) => {
                    // 根据配置中的组件名称找到其定义
                    const compDef = reflectConfig(colComp.component)
                    if (compDef) {
                      restoreElement(compDef, colComp, compUUID)
                    }
                    return compDef
                  })
                  return col
                })
              }
            })
          })
          compDef.selected = false
          compDef.id = ele.id || uuidv4()
        }
      } else {
        compDef = reflectConfig(ele.component)
        if (compDef) {
          restoreElement(compDef, ele, compUUID)
        }
      }
      return compDef
    })
  }
}

function reflectConfig(compName: string) {
  return JSON.parse(JSON.stringify(viewEditorStore.dragResources.find(i => i.drag.compName === compName)))
}

function restoreElement(compDef: any, ele: any, compUUID: Ref<number>) {
  Object.keys(compDef.data).forEach(item => {
    Object.keys(compDef.data[item]).forEach(key => {
      if (ele[item] && ![null, undefined].includes(ele[item][key])) {
        compDef.data[item][key] = ele[item][key]
      }
    })
  })
  compDef.selected = false
  compDef.id = ele.id || uuidv4()
  countKeyUUID(compDef.data.dataModel.model, compUUID)
}


function countKeyUUID(model: string, compUUID: Ref<number>) {
  if (/^key_[1-9][0-9]*$/.test(model)) {
    compUUID.value = Math.max(compUUID.value, Number(model.split('_')[1]))
  }
}

export {
  getConfig,
  restoreConfig
}